<?php
namespace app\data_magic\logic;

class Access
{
    /**
     * @var string $current_user_id 当前用户ID
     * @var string[] $current_roles 当前用户角色
     * @var string[] $roles 允许访问的角色
     * @var int $public_level 公开级别
     *  用来规定当用户不拥有权限控制要求的角色时，是否对用户公开数据
     *  0,不公开(protected);1,所有者(owner);2,用户(user);3,全部(public)
     *  $auth 为空时，默认为 public
     *  $auth 不为空，但没有指定 $public_level ,默认为 protected
     */
    public $current_user_id="";
    public $current_roles=[];
    protected $roles=[];
    protected $public_level=0;

    /**
     * 设置访问条件
     * @param string $auth 访问条件
     *  包含角色和公开级别,以`,`分隔
     */
    function setAuth($auth)
    {
        if(!$auth){
            $this->public_level=3;
            return $this;
        }
        $this->public_level=0;
        $auth_list=explode(",",$auth);
        foreach($auth_list as &$item){
            $result=array_search($item,["protected","owner","user","public"]);
            if($result!==false){
                $this->public_level=$result;
                unset($item);
            }
        }
        $this->roles=$auth_list;
    }

    /**
     * 检查是否有权访问当前操作关联的所有数据
     */
    public function checkAuth()
    {
        if($this->public_level === 3){
            return true;
        }
        elseif($this->public_level === 2 && $this->current_user_id){
            return true;
        }
        else{
            foreach($this->current_roles as $role){
                if(in_array($role,$this->roles)){
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 检查一条数据是否允许用户访问
     * @param string $user_id_field 记录user_id的字段名
     * @param string[] $data 要检查的数据
     * @return bool
     */
    public function checkItem($user_id_field,$data)
    {
        if($this->checkAuth()){
            return true;
        }
        if($this->public_level === 1 && $this->current_user_id){
            if($data[$user_id_field]===$this->current_user_id){
                return true;
            }
        }
        return false;
    }

    /**
     * 在数据库搜索条件中插入过滤用户可以访问的数据的条件
     * 不需要过滤时返回 false
     * @param string $user_id_field 记录user_id的字段名
     * @return string|false
     */
    public function filter($user_id_field)
    {
        if($this->checkAuth()){
            return false;
        }
        if($this->public_level === 1 && $this->current_user_id){
            return "`".$user_id_field."` = ".$this->current_user_id;
        }
        return false;
    }
}
